﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.ComponentModel;
using BrainTechLLC.WPF;
using BrainTechLLC.ImageOperators;
using System.Drawing;
using BrainTechLLC;
using System.Threading;
using System.Diagnostics;

namespace ImageAppDataModels
{
    public partial class FileImage : BaseNotifyPropertyChangedUI, IHasBitmap, INotifyPropertyChanged, IObjectLock, IFileImage
    {
        protected Bitmap _bitmap;        
        
        public bool BitmapLoaded
        {
            get { return _bitmap != null; }
        }

        public Bitmap BitmapCached
        {
            get
            {
                if (_deleted) 
                {
                    if (_bitmap != null)
                    {
                        _bitmap.Dispose();
                        _bitmap = null;
                    }
                    return null;
                }

                return _bitmap;
            }
            set
            {
                if (_bitmap != value)
                {
                    if (_bitmap != null)
                    {
                        _bitmap.Dispose();
                    }

                    _bitmap = value;                    

                    if (_bitmap != null)
                    {                        
                        _originalBitmapWidth = _bitmap.Width;
                        _originalBitmapHeight = _bitmap.Height;
                        _originalBitmapPixelFormat = _bitmap.PixelFormat;
                        RecentlyUsedFileImages.RecentlyUsedBitmaps.MarkItemRecentlyUsed(this);
                        OnPropertyChanged("OriginalBitmapWidth", "OriginalBitmapHeight", "OriginalBitmapPixelFormat");
                    }
                }
            }
        }

        protected Bitmap InitiateBitmapLoad()
        {
            Bitmap bm = _bitmap;

            if (bm == null) 
            {
                bm = EnsureBitmapLoaded();
            }

            return bm;
        }

        public Bitmap Bitmap
        {
            get
            {
                if (_deleted)
                {
                    _bitmap = null;
                    return null;
                }
                
                if (_bitmap == null)
                {                    
                    InitiateBitmapLoad();
                }

                return _bitmap;
            }
            set
            {
                if (_bitmap != value)
                {
                    if (_bitmap != null)
                    {
                        _bitmap.Dispose();
                        _bitmap = null;
                    }

                    _bitmap = value;                    

                    if (_bitmap != null)
                    {
                        _originalBitmapWidth = _bitmap.Width;
                        _originalBitmapHeight = _bitmap.Height;
                        _originalBitmapPixelFormat = _bitmap.PixelFormat;
                        RecentlyUsedFileImages.RecentlyUsedBitmaps.MarkItemRecentlyUsed(this);
                        MarkEverythingDirty(true, true, true);
                        OnPropertyChanged("OriginalBitmapWidth", "OriginalBitmapHeight", "OriginalBitmapPixelFormat");
                    }                                            

                    OnPropertyChanged("Bitmap");
                }
            }
        }

        public double AspectRatio
        {
            get
            {
                if (Bitmap == null)
                    return 0D;

                return ((double)_originalBitmapWidth / (double)_originalBitmapHeight);
            }
        }
        
        public byte[] EnsureImageBytesLoaded()
        {
            byte[] result = _imageBytes;

            if (result == null)
            {
                result = Load();
            }

            return result;
        }

        public Bitmap EnsureBitmapLoaded()
        {
            return EnsureBitmapLoaded(true);
        }

        public Bitmap EnsureBitmapLoaded(bool raiseEvents)
        {
            Bitmap bm = _bitmap;

            if (_bitmap == null) 
            {                
                byte[] bytes = EnsureImageBytesLoaded();
                
                if ((_bitmap == null) && bytes != null)
                {
                    try
                    {
                        bm = SetBitmapFromImageBytes(bytes);
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.ToString());
                        bm = null;
                    }

                    if (bm != null)
                    {
                        if (!raiseEvents)
                        {
                            SetSuspendPropertyChanged(true);
                        }

                        // HEREHERE:
                        // EnterMonitor(_lockObject, 20);

                        try
                        {
                            if (_bitmap == null) 
                            {
                                Bitmap = bm;
                                _originalBitmapWidth = bm.Width;
                                _originalBitmapHeight = bm.Height;
                                _originalBitmapPixelFormat = bm.PixelFormat;
                                OnPropertyChanged("WidthHeight");                                
                            }
                        }
                        finally
                        {
                            // HEREHERE:
                            // Monitor.Exit(_lockObject);
                        }

                        if (!raiseEvents)
                        {
                            SetSuspendPropertyChanged(false);
                        }
                    }
                }

                if (bm == null)
                    bm = _bitmap;
            }

            return bm;
        }

        public long GetByteEstimateForBitmapCached()
        {
            return BitmapCached.GetByteEstimate(this._originalBitmapWidth, this._originalBitmapHeight, this._originalBitmapPixelFormat);
        }

        public long GetByteEstimateForThumbnailCached()
        {
            if (ThumbnailObject != null)
            {
                return ThumbnailObject.GetByteEstimateForThumbnailCached();
            }
            return 0;
        }
    }
}
